package com.tobby.camel.camelinaction.chapter5.errorhandler;

import org.apache.camel.Exchange;
import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.impl.JndiRegistry;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Test;

public class RouteScopeTest extends CamelTestSupport {

	@Override
	public void setUp() throws Exception {
		deleteDirectory("target/orders");
		super.setUp();
	}

	@Override
	protected JndiRegistry createRegistry() {
		JndiRegistry registry = new JndiRegistry();
		registry.bind("orderService", new OrderService());
		return registry;
	}

	@Test
	public void testOrderOK() throws InterruptedException {
		// we expected the file to be converted to csv and routed to the 2nd route
		MockEndpoint endpoint = getMockEndpoint("mock:file");
		endpoint.expectedMessageCount(1);

		// We expected the 2nd route to complete
		MockEndpoint mock = getMockEndpoint("mock:queue.order");
		mock.expectedBodiesReceived("amount=1,name=Camel in Action,id=123,status=OK");

		template.sendBodyAndHeader("file://target/orders",
				"amount=1#name=Camel in Action", Exchange.FILE_NAME, "order.txt");

		assertMockEndpointsSatisfied();
	}

	@Test
	public void testOrderActiveMQ() throws InterruptedException {
		// we expected the file to be converted to csv and routed to the 2nd route
		MockEndpoint endpoint = getMockEndpoint("mock:file");
		endpoint.expectedMessageCount(1);

		// we do not expected the 2nd route to complete
		MockEndpoint mock = getMockEndpoint("mock:queue.order");
		mock.expectedMessageCount(0);

		template.sendBodyAndHeader("file://target/orders",
				"amount=1#name=ActiveMQ in Action", Exchange.FILE_NAME, "order.txt");

		// wait 10 seconds to let this test run
		Thread.sleep(10000);
		assertMockEndpointsSatisfied();

	}

	@Test
	public void testXmlOrderFail() throws InterruptedException {
		// we do not expected the file to be converted to csv
		MockEndpoint endpoint = getMockEndpoint("mock:file");
		endpoint.expectedMessageCount(0);

		// and therefore no messages in the 2nd route
		MockEndpoint mock = getMockEndpoint("mock:queue.order");
		mock.expectedMessageCount(0);

		template.sendBodyAndHeader("file://target/orders",
				"<?xml version=\"1.0\"?><order><amount>1</amount><name>Camel in Action</name></order>",
				Exchange.FILE_NAME, "order2.xml");

		// wait 5 seconds to let this test run
		Thread.sleep(5000);
		assertMockEndpointsSatisfied();

	}

	@Override
	protected RouteBuilder createRouteBuilder() {
		return new RouteBuilder() {

			@Override
			public void configure() throws Exception {
				// this is the default error handler which is context scoped
				errorHandler(defaultErrorHandler().maximumRedeliveries(2)
						.redeliveryDelay(1000).retryAttemptedLogLevel(LoggingLevel.WARN));
				// this first route will fallback and use the context scoped default error
				// handler
				from("file://target/orders?delay=10000").bean("orderService", "toCsv")
						.to("mock:file").to("seda:queue.inbox");

				// this 2nd route has a route scoped DeadLetterChannel as its error
				// handler
				from("seda:queue.inbox")
						.errorHandler(deadLetterChannel("log:DLC").maximumRedeliveries(5)
								.retryAttemptedLogLevel(LoggingLevel.INFO)
								.redeliveryDelay(250).backOffMultiplier(2))
						.bean("orderService", "validate").bean("orderService", "enrich")
						.to("mock:queue.order");
			}
		};
	}

}
